// HSS.Forms.Docking.DockPaneCaption.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       DockPaneCaption.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace HSS.Forms.Docking
{
	internal class DockPaneCaption : DockPaneCaptionBase
	{
		private sealed class InertButton : InertButtonBase
		{
			private Bitmap _image, _imageAutoHide;

			public InertButton(DockPaneCaption dockPaneCaption, Bitmap image, Bitmap imageAutoHide)
				: base()
			{
				_dockPaneCaption = dockPaneCaption;
				_image = image;
				_imageAutoHide = imageAutoHide;
				RefreshChanges();
			}

			private DockPaneCaption _dockPaneCaption;
			private DockPaneCaption DockPaneCaption
			{
				get { return _dockPaneCaption; }
			}

			public bool IsAutoHide
			{
				get { return DockPaneCaption.DockPane.IsAutoHide; }
			}

			public override Bitmap Image
			{
				get { return IsAutoHide ? _imageAutoHide : _image; }
			}

			protected override void OnRefreshChanges()
			{
				if (DockPaneCaption.TextColor != ForeColor)
				{
					ForeColor = DockPaneCaption.TextColor;
					Invalidate();
				}
			}
		}

		#region consts
		private const int _TextGapTop = 0;
		private const int _TextGapLeft = 2;
		private const int _TextGapBottom = 2;
		private const int _TextGapRight = 3;
		private const int _ButtonGapBetween = 1;
		private const int _ButtonGapTop = 0;
		private const int _ButtonGapLeft = 1;
		private const int _ButtonGapBottom = 2;
		private const int _ButtonGapRight = 2;
		#endregion

		private static Bitmap _imageButtonClose;
		private static Bitmap ImageButtonClose
		{
			get
			{
				if (_imageButtonClose == null)
					_imageButtonClose = Resources.DockPane_Close;

				return _imageButtonClose;
			}
		}

		private InertButton _buttonClose;
		private InertButton ButtonClose
		{
			get
			{
				if (_buttonClose == null)
				{
					_buttonClose = new InertButton(this, ImageButtonClose, ImageButtonClose);
					_toolTip.SetToolTip(_buttonClose, ToolTipClose);
					_buttonClose.Click += new EventHandler(Close_Click);
					Controls.Add(_buttonClose);
				}

				return _buttonClose;
			}
		}

		private static Bitmap _imageButtonAutoHide;
		private static Bitmap ImageButtonAutoHide
		{
			get
			{
				if (_imageButtonAutoHide == null)
					_imageButtonAutoHide = Resources.DockPane_AutoHide;

				return _imageButtonAutoHide;
			}
		}

		private static Bitmap _imageButtonDock;
		private static Bitmap ImageButtonDock
		{
			get
			{
				if (_imageButtonDock == null)
					_imageButtonDock = Resources.DockPane_Dock;

				return _imageButtonDock;
			}
		}

		private InertButton _buttonAutoHide;
		private InertButton ButtonAutoHide
		{
			get
			{
				if (_buttonAutoHide == null)
				{
					_buttonAutoHide = new InertButton(this, ImageButtonDock, ImageButtonAutoHide);
					_toolTip.SetToolTip(_buttonAutoHide, ToolTipAutoHide);
					_buttonAutoHide.Click += new EventHandler(AutoHide_Click);
					Controls.Add(_buttonAutoHide);
				}

				return _buttonAutoHide;
			}
		}

		private static Bitmap _imageButtonOptions;
		private static Bitmap ImageButtonOptions
		{
			get
			{
				if (_imageButtonOptions == null)
					_imageButtonOptions = Resources.DockPane_Option;

				return _imageButtonOptions;
			}
		}

		private InertButton _buttonOptions;
		private InertButton ButtonOptions
		{
			get
			{
				if (_buttonOptions == null)
				{
					_buttonOptions = new InertButton(this, ImageButtonOptions, ImageButtonOptions);
					_toolTip.SetToolTip(_buttonOptions, ToolTipOptions);
					_buttonOptions.Click += new EventHandler(Options_Click);
					Controls.Add(_buttonOptions);
				}
				return _buttonOptions;
			}
		}

		private IContainer _components;
		private IContainer Components
		{
			get { return _components; }
		}

		private ToolTip _toolTip;

		public DockPaneCaption(DockPane pane)
			: base(pane)
		{
			SuspendLayout();

			_components = new Container();
			_toolTip = new ToolTip(Components);

			ResumeLayout();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
				Components.Dispose();
			base.Dispose(disposing);
		}

		private static int TextGapTop
		{
			get { return _TextGapTop; }
		}

		private static Font TextFont
		{
			get { return SystemInformation.MenuFont; }
		}

		private static int TextGapBottom
		{
			get { return _TextGapBottom; }
		}

		private static int TextGapLeft
		{
			get { return _TextGapLeft; }
		}

		private static int TextGapRight
		{
			get { return _TextGapRight; }
		}

		private static int ButtonGapTop
		{
			get { return _ButtonGapTop; }
		}

		private static int ButtonGapBottom
		{
			get { return _ButtonGapBottom; }
		}

		private static int ButtonGapLeft
		{
			get { return _ButtonGapLeft; }
		}

		private static int ButtonGapRight
		{
			get { return _ButtonGapRight; }
		}

		private static int ButtonGapBetween
		{
			get { return _ButtonGapBetween; }
		}

		private static string _toolTipClose;
		private static string ToolTipClose
		{
			get
			{
				if (_toolTipClose == null)
					_toolTipClose = Strings.DockPaneCaption_ToolTipClose;
				return _toolTipClose;
			}
		}

		private static string _toolTipOptions;
		private static string ToolTipOptions
		{
			get
			{
				if (_toolTipOptions == null)
					_toolTipOptions = Strings.DockPaneCaption_ToolTipOptions;

				return _toolTipOptions;
			}
		}

		private static string _toolTipAutoHide;
		private static string ToolTipAutoHide
		{
			get
			{
				if (_toolTipAutoHide == null)
					_toolTipAutoHide = Strings.DockPaneCaption_ToolTipAutoHide;
				return _toolTipAutoHide;
			}
		}

		private static Blend _activeBackColorGradientBlend;
		private static Blend ActiveBackColorGradientBlend
		{
			get
			{
				if (_activeBackColorGradientBlend == null)
				{
					Blend blend = new Blend(2);

					blend.Factors = new float[] { 0.5F, 1.0F };
					blend.Positions = new float[] { 0.0F, 1.0F };
					_activeBackColorGradientBlend = blend;
				}

				return _activeBackColorGradientBlend;
			}
		}

		private static Color ActiveBackColorGradientBegin
		{
			get { return Color.FromArgb(215, 228, 242); }
		}

		private static Color ActiveBackColorGradientEnd
		{
			get { return Color.FromArgb(153, 180, 209); }
		}

		private static Color InactiveBackColor
		{
			get { return Color.FromArgb(235, 247, 250); }
		}

		private static Color ActiveTextColor
		{
			get { return SystemColors.ActiveCaptionText; }
		}

		private static Color InactiveTextColor
		{
			get { return SystemColors.ControlText; }
		}

		private Color TextColor
		{
			get { return DockPane.IsActivated ? ActiveTextColor : InactiveTextColor; }
		}

		private static TextFormatFlags _textFormat =
			TextFormatFlags.SingleLine |
			TextFormatFlags.EndEllipsis |
			TextFormatFlags.VerticalCenter;

		private TextFormatFlags TextFormat
		{
			get
			{
				if (RightToLeft == RightToLeft.No)
					return _textFormat;
				else
					return _textFormat | TextFormatFlags.RightToLeft | TextFormatFlags.Right;
			}
		}

		protected internal override int MeasureHeight()
		{
			int height = TextFont.Height + TextGapTop + TextGapBottom;

			if (height < ButtonClose.Image.Height + ButtonGapTop + ButtonGapBottom)
				height = ButtonClose.Image.Height + ButtonGapTop + ButtonGapBottom;

			return height;
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			DrawCaption(e.Graphics);
		}

		private void DrawCaption(Graphics g)
		{
			if (ClientRectangle.Width == 0 || ClientRectangle.Height == 0)
				return;

			if (this.DockPane.DockState == DockState.Document)
				return;

			if (DockPane.IsActivated)
			{
				using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, ActiveBackColorGradientBegin, ActiveBackColorGradientEnd, LinearGradientMode.Vertical))
				{
					brush.Blend = ActiveBackColorGradientBlend;
					g.FillRectangle(brush, ClientRectangle);
				}
			}
			else
			{
				using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, ControlPaint.LightLight(ActiveBackColorGradientEnd), ControlPaint.Light(ActiveBackColorGradientBegin), LinearGradientMode.Vertical))
				{
					g.FillRectangle(brush, ClientRectangle);
				}
			}

			Rectangle rectCaption = ClientRectangle;

			Rectangle rectCaptionText = rectCaption;
			rectCaptionText.X += TextGapLeft;
			rectCaptionText.Width -= TextGapLeft + TextGapRight;
			rectCaptionText.Width -= ButtonGapLeft + ButtonClose.Width + ButtonGapRight;
			if (ShouldShowAutoHideButton)
				rectCaptionText.Width -= ButtonAutoHide.Width + ButtonGapBetween;
			if (HasTabPageContextMenu)
				rectCaptionText.Width -= ButtonOptions.Width + ButtonGapBetween;
			rectCaptionText.Y += TextGapTop;
			rectCaptionText.Height -= TextGapTop + TextGapBottom;
			TextRenderer.DrawText(g, DockPane.CaptionText, TextFont, DrawHelper.RtlTransform(this, rectCaptionText), TextColor, TextFormat);
		}

		protected override void OnLayout(LayoutEventArgs levent)
		{
			SetButtonsPosition();
			base.OnLayout(levent);
		}

		protected override void OnRefreshChanges()
		{
			SetButtons();
			Invalidate();
		}

		private bool CloseButtonEnabled
		{
			get { return (DockPane.ActiveContent != null) ? DockPane.ActiveContent.DockHandler.CloseButton : false; }
		}

		private bool ShouldShowAutoHideButton
		{
			get { return !DockPane.IsFloat; }
		}

		private void SetButtons()
		{
			ButtonClose.Enabled = CloseButtonEnabled;
			ButtonAutoHide.Visible = ShouldShowAutoHideButton;
			ButtonOptions.Visible = HasTabPageContextMenu;
			ButtonClose.RefreshChanges();
			ButtonAutoHide.RefreshChanges();
			ButtonOptions.RefreshChanges();

			SetButtonsPosition();
		}

		private void SetButtonsPosition()
		{
			// set the size and location for close and auto-hide buttons
			Rectangle rectCaption = ClientRectangle;
			int buttonWidth = ButtonClose.Image.Width;
			int buttonHeight = ButtonClose.Image.Height;
			int height = rectCaption.Height - ButtonGapTop - ButtonGapBottom;
			if (buttonHeight < height)
			{
				buttonWidth = buttonWidth * (height / buttonHeight);
				buttonHeight = height;
			}
			Size buttonSize = new Size(buttonWidth, buttonHeight);
			int x = rectCaption.X + rectCaption.Width - 1 - ButtonGapRight - _buttonClose.Width;
			int y = rectCaption.Y + ButtonGapTop;
			Point point = new Point(x, y);
			ButtonClose.Bounds = DrawHelper.RtlTransform(this, new Rectangle(point, buttonSize));
			point.Offset(-(buttonWidth + ButtonGapBetween), 0);
			ButtonAutoHide.Bounds = DrawHelper.RtlTransform(this, new Rectangle(point, buttonSize));
			if (ShouldShowAutoHideButton)
				point.Offset(-(buttonWidth + ButtonGapBetween), 0);
			ButtonOptions.Bounds = DrawHelper.RtlTransform(this, new Rectangle(point, buttonSize));
		}

		private void Close_Click(object sender, EventArgs e)
		{
			DockPane.CloseActiveContent();
		}

		private void AutoHide_Click(object sender, EventArgs e)
		{
			DockPane.DockState = DockHelper.ToggleAutoHideState(DockPane.DockState);
		}

		private void Options_Click(object sender, EventArgs e)
		{
			ShowTabPageContextMenu(PointToClient(Control.MousePosition));
		}

		protected override void OnRightToLeftChanged(EventArgs e)
		{
			base.OnRightToLeftChanged(e);
			PerformLayout();
		}
	}
}